package ED2;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public final class ManipulaDados
{
    private LeiuraDados lerDados;
    
    public ManipulaDados()
    {
        lerDados = new LeiuraDados();
    }
    
    public ManipulaDados(String rootPath)
    {
        lerDados = new LeiuraDados(rootPath);
    }

    public ArrayList<AlunoBean> getAmigos(int rm)
    {
        ArrayList<AlunoBean> amigos = new ArrayList<AlunoBean>();
        
        if(lerDados.getData().containsKey(rm))
        {
            AlunoBean aluno = lerDados.getData().get(rm);
            
            for(int amigoRm : aluno.getvizinhoRm())
            {
                if(lerDados.getData().containsKey(amigoRm))
                {
                    amigos.add(lerDados.getData().get(amigoRm));
                }
                else
                {
                    amigos.add(new AlunoBean(amigoRm));
                }
            }
        }
        
        return amigos;
    }
    
    public ArrayList<AlunoBean> getAllEnrolledAlunos()
    {
        ArrayList<AlunoBean> alunos = new ArrayList<AlunoBean>();
        
        for(Map.Entry<Integer, AlunoBean> entry : lerDados.getData().entrySet())
        {
            AlunoBean value = entry.getValue();
            
            alunos.add(value);
        }
        
        return alunos;
    }
    
    public ArrayList<AlunoBean> getAllAlunos()
    {
        ArrayList<AlunoBean> alunos = new ArrayList<AlunoBean>();
        
        for(Map.Entry<Integer, AlunoBean> entry : lerDados.getData().entrySet())
        {
            AlunoBean value = entry.getValue();
            
            if(!alunos.contains(value))
            {
                alunos.add(value);
            }
            
            for(int amigoRm : value.getvizinhoRm())
            {
                AlunoBean amigo = lerDados.getData().get(amigoRm);
                
                if(amigo == null)
                {
                    amigo = new AlunoBean(amigoRm);
                }
                
                if(!alunos.contains(amigo))
                {
                    alunos.add(amigo);
                }
            }
        }
        
        return alunos;
    }
    
    public ArrayList<ArrayList<AlunoBean>> getTouchableAlunos(int rm)
    {
        return getTouchableAlunos(rm, -1);
    }
    
    public ArrayList<ArrayList<AlunoBean>> getTouchableAlunos(int rm, int max)
    {   
        ArrayList<AlunoBean> alunosHistory = new ArrayList<AlunoBean>();
        HashMap<Integer, ArrayList<AlunoBean>> hashMapAlunos = new HashMap<Integer, ArrayList<AlunoBean>>();
        
        getTouchableAlunos(rm, -1, alunosHistory, hashMapAlunos, max, 0);
        
        ArrayList<ArrayList<AlunoBean>> touchableAlunos = new ArrayList<ArrayList<AlunoBean>>();
        
        Iterator iterator = hashMapAlunos.entrySet().iterator();
        
        while(iterator.hasNext())
        {
            Map.Entry pairs = (Map.Entry) iterator.next();
            
            ArrayList<AlunoBean> alunos = (ArrayList<AlunoBean>) pairs.getValue();
            
            touchableAlunos.add(alunos);
            
            iterator.remove();
        }
        
        return touchableAlunos;
    }
    
    public ArrayList<AlunoBean> getUntouchableAlunos(int rm)
    {
        ArrayList<AlunoBean> allAlunos = getAllAlunos();
        ArrayList<ArrayList<AlunoBean>> touchableAlunos = getTouchableAlunos(rm);
        
        ArrayList<AlunoBean> untouchableAlunos = new ArrayList<AlunoBean>();
        
        for(AlunoBean aluno : allAlunos)
        {
            boolean touchableAlunosContains = false;
            
            for(ArrayList<AlunoBean> alunos : touchableAlunos)
            {
                if((touchableAlunosContains = alunos.contains(aluno)))
                {
                    break;
                }
            }
            
            if(!touchableAlunosContains && aluno.getRm() != rm)
            {
                untouchableAlunos.add(aluno);
            }
        }
        
        return untouchableAlunos;
    }
    
    private void getTouchableAlunos(int baseRm, int currentRm, ArrayList<AlunoBean> alunosHistory, HashMap<Integer, ArrayList<AlunoBean>> hashMapAlunos, int maxDeep, int currentDeep)
    {
        if(currentDeep++ < maxDeep || maxDeep == -1)
        {
            int rm = currentRm == -1? baseRm : currentRm;

            ArrayList<AlunoBean> amigos = getAmigos(rm);

            for(AlunoBean amigo : amigos)
            {
                if(amigo.getRm() != baseRm)
                {
                    if(!alunosHistory.contains(amigo))
                    {
                        alunosHistory.add(amigo);
                        
                        if(!hashMapAlunos.containsKey(currentDeep))
                        {
                            hashMapAlunos.put(currentDeep, new ArrayList<AlunoBean>());
                        }
                        
                        hashMapAlunos.get(currentDeep).add(amigo);

                        getTouchableAlunos(baseRm, amigo.getRm(), alunosHistory, hashMapAlunos, maxDeep, currentDeep);
                    }
                }
            }
        }
    }
}
